package com.neu.cpsp.controller;
/*
    @author neu.xiangwenjuan
    @create 2022/4/15
*/

import com.auth0.jwt.interfaces.DecodedJWT;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.neu.cpsp.dao.EmployeeMapper;
import com.neu.cpsp.dao.EvaluateRecordMapper;
import com.neu.cpsp.dao.EvaluateRecordToEmployeeMapper;
import com.neu.cpsp.dao.RegulationTimesMapper;
import com.neu.cpsp.pojo.*;
import com.neu.cpsp.service.*;
import com.neu.cpsp.service.impl.EvaluateRecordServiceImpl;
import com.neu.cpsp.util.JWTUtils;
import com.neu.cpsp.util.result.Result;
import com.neu.cpsp.util.result.ResultGenerator;
import io.swagger.annotations.ApiOperation;
import org.apache.catalina.LifecycleState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@CrossOrigin
@RestController
@RequestMapping("/evaluateRecordDetail")
public class EvaluateRecordDetailController {

    @Autowired
    private EvaluateRecordMapper evaluateRecordMapper;

    @Autowired
    private RegulationTimesMapper regulationTimesMapper;

    @Autowired
    private EvaluateRecordToEmployeeMapper toEmployeeMapper;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private EvaluateRecordDetailService detailService;

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private EvaluateRecordService evaluateRecordService;

    @Autowired
    private EvaluateRecordToEmployeeService toEmployeeService;

    @Autowired
    private RegulationDetailAndTimesService timesService;

    private EmployeeController employeeController = new EmployeeController();

    @ApiOperation("获得每次违章肇事者的详细记录")
    @RequestMapping(value = "/getEvaluateDetail", method = RequestMethod.GET)
    @ResponseBody
    private Result getEvaluateDetail(@RequestParam(defaultValue = "1") Integer pageNum,
                                     @RequestParam(defaultValue = "10") Integer pageSize,
                                     HttpServletRequest request) {
        String token = request.getHeader("token");
        DecodedJWT verify = JWTUtils.verify(token);
        // 得到用户的工号，确认部门，根据角色判断用户权限。
        String role = verify.getClaim("role").asString();
        String jobNumber = verify.getClaim("jobNumber").asString();
        // 登录的员工
        EmployeeEntity employee = employeeService.selectByJobNumber(jobNumber);
        List<EvaluateRecordDetailEn> list = new ArrayList<>();
        PageHelper.startPage(pageNum,pageSize);
        list = detailService.selectAllDetail(null);
        PageInfo pageInfo = PageInfo.of(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    /**
     * 根据name或者idCard模糊查询某个员工的违章记录。
     * @param employeeInfo
     * @return
     */
    @ApiOperation("获得某个员工的详细违章记录")
    @RequestMapping(value = "/getDetailByEmployee", method = RequestMethod.GET)
    @ResponseBody
    private Result getDetailByEmployee(String employeeInfo) {
        List<EvaluateRecordDetailEn> employeeList = detailService.selectDetailByEmployee(employeeInfo);
        if (employeeList.size() > 0) {
            return ResultGenerator.genSuccessResult(employeeList);
        }else {
            List<EmployeeEntity> employees = employeeService.selectByName(employeeInfo);
            for (EmployeeEntity employee:employees) {
                List<EvaluateRecordDetailEn> list = detailService.selectDetailByEmployee(employee.getIdCard());
                employeeList.addAll(list);
            }
            return ResultGenerator.genSuccessResult(employeeList);
        }
    }

    /**
     * 添加开始时间、结束时间筛选项。类型是YYYY-MM-dd HH:mm:ss
     * @param pageNum
     * @param pageSize
     * @param department
     * @param teamGroup
     * @return
     */
    @ApiOperation("根据部门或班组筛选违章记录")
    @RequestMapping(value = "/getDetailByDepart", method = RequestMethod.GET)
    @ResponseBody
    private Result getDetailByDepart(@RequestParam(defaultValue = "1") Integer pageNum,
                                     @RequestParam(defaultValue = "10") Integer pageSize,
                                     @RequestParam(required = false) String department,
                                     @RequestParam(required = false) String teamGroup,
                                     @RequestParam(required = false) String startTime,
                                     @RequestParam(required = false) String endTime) {
        if (startTime == null) {// 当前季度第一天。
            startTime = getQuarterStart(new Date());
        }
        if (endTime == null) {// 当前季度最后一天。
            endTime = getQuarterEnd(new Date());
        }
        PageHelper.startPage(pageNum,pageSize);
        List<EvaluateRecordDetailEn> list = detailService.selectByDepart(department, teamGroup, startTime, endTime);
        PageInfo pageInfo = PageInfo.of(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }


    @ApiOperation("添加违章记录")
    @RequestMapping(value = "/insertDetail", method = RequestMethod.POST)
    @ResponseBody
    private Result insertDetail(@RequestParam String employeeIdCard,
                                @RequestParam Integer regulationTypeId,
                                @RequestParam Integer regulationDetailId,
                                @RequestParam(required = false) Integer year,
                                @RequestParam(required = false) Integer session) {
        EvaluateRecordDetail evaluateRecordDetail = new EvaluateRecordDetail();
        EmployeeEntity employee = employeeService.selectByCard(employeeIdCard);
        if (year == null && session == null) {
            year = Calendar.getInstance().get(Calendar.YEAR);
            session = employeeController.getSeason(new Date());
        }
        evaluateRecordDetail.setYear(year);
        evaluateRecordDetail.setQuarter(session);
        evaluateRecordDetail.setEmployeeIdCard(employeeIdCard);
        evaluateRecordDetail.setEmployeeDepart(employee.getDepartment().getDepartmentId());

        evaluateRecordDetail.setRegulationTypeId(regulationTypeId);
        evaluateRecordDetail.setRegulationDetailId(regulationDetailId);
        SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        evaluateRecordDetail.setDateTime(sdf.format(new Date()));
        if (employee.getTeamGroup() == null) {
            evaluateRecordDetail.setEmployeeGroup("");
        }else {
            evaluateRecordDetail.setEmployeeGroup(employee.getTeamGroup().getId()+"");
        }
        int tag = detailService.insertDetail(evaluateRecordDetail);
        if (tag < 1) {
            return ResultGenerator.genFailResult("插入数据失败！");
        }
        // 插入到detail表之后，需要将相应的信息添加到evaluate_record表中，保存统计出来的信息，并根据违章次数来添加关联人员。
        // 调用evaluate_record表中的插入语句。
        evaluateRecordService.insertEvaluateRecord(evaluateRecordDetail);
        return ResultGenerator.genSuccessResult("插入数据成功！");
    }


    @ApiOperation("删除违章记录")
    @RequestMapping(value = "/deleteDetail", method = RequestMethod.POST)
    @ResponseBody
    private Result deleteDetail(Integer id) {
        EvaluateRecordDetail detail = detailService.selectByPrimaryKey(id);
        int year = detail.getYear();
        int session = detail.getQuarter();
        System.out.println(session);
        // 查找evaluate_record表里面的次数。
        EvaluateRecordEntity entity = evaluateRecordService.checkTimes(year, session, detail.getEmployeeIdCard(), detail.getEmployeeDepart(),
                detail.getRegulationTypeId(), detail.getRegulationDetailId());
        // 如果evaluate_record的次数为1，直接删去了，
        if (entity.getTimes() == 1) {
            // 直接删除全部记录。
            evaluateRecordService.deleteInfoById(entity.getId());
            toEmployeeService.deleteInfoByRecordId(entity.getId());
            detailService.deleteRecordDetail(id);
            return ResultGenerator.genSuccessResult("删除数据成功！");
        }
        // 如果要删除的这条记录，肇事者犯过多次，大于最大次数，减去一次对关联人员扣减比例无影响。
        int maxTimes = timesService.maxTimesByDetailId(detail.getRegulationDetailId());
        entity.setTimes(entity.getTimes() - 1);
        if (entity.getTimes() >= maxTimes) {
            // 更新汇总表的次数.
            evaluateRecordService.updateByIdSelective(entity);
            detailService.deleteRecordDetail(id);
            return ResultGenerator.genSuccessResult("删除数据成功！");
        }

        // 如果肇事者违章次数小于最大次数且大于1，还需要更新关联人员的信息。
        toEmployeeService.deleteInfoByRecordId(entity.getId());
        evaluateRecordService.deleteInfoById(entity.getId());
        detailService.deleteRecordDetail(id);
        // 还需要更新evaluate_record表和to_employee表里面的内容。
        entity.setId(null);
        boolean tag = insertToTable(entity);
        return ResultGenerator.genSuccessResult("删除数据成功！");
    }

    /**
     *
     * @param id  根据违章id获得违章信息。
     * @return
     */
    @ApiOperation("点击修改按钮后，得到该违章的信息")
    @RequestMapping(value = "/getUpdateBeforeDetail", method = RequestMethod.GET)
    @ResponseBody
    private Result getUpdateBeforeDetail(Integer id){
        EvaluateRecordDetailEn recordDetail = detailService.selectDetailById(id);
        if (recordDetail != null) {
            return ResultGenerator.genSuccessResult(recordDetail);
        }else {
            return ResultGenerator.genFailResult("获取失败！");
        }
    }

    /**
     *
     *
     * @param detailId   与上面获得违章信息的id一致。
     * @param employeeIdCard  选择的新的员工的身份证号
     * @param regulationTypeId  选择的新的违章类型id
     * @param regulationDetailId  选择的新的违章细节id
     * @return
     */
    @ApiOperation("更新违章记录")
    @RequestMapping(value = "/updateEvaluateDetail", method = RequestMethod.POST)
    @ResponseBody
    private Result updateEvaluateDetail(@RequestParam Integer detailId,
                                        @RequestParam Integer year,
                                        @RequestParam Integer quarter,
                                        @RequestParam String employeeIdCard,
                                        @RequestParam Integer regulationTypeId,
                                        @RequestParam Integer regulationDetailId) {
        if (detailService.selectDetailById(detailId) != null && employeeIdCard != null && regulationTypeId != null && regulationDetailId != null) {
            // 先根据违章id删除该违章记录。
            Result result = deleteDetail(detailId);
            if (result.getCode() != 200) {
                return ResultGenerator.genFailResult("删除记录失败！");
            }
            // 再根据身份证号，违章类型id，违章细节id重新添加。
            Result result1 = insertDetail(employeeIdCard,regulationTypeId,regulationDetailId,year, quarter);
            if (result1.getCode() != 200) {
                return ResultGenerator.genFailResult("添加更新后记录失败！");
            }
            return ResultGenerator.genSuccessResult("更新违章记录成功！");
        }else {
            return ResultGenerator.genFailResult("参数不符合要求！");
        }
    }

    private boolean insertToTable(EvaluateRecordEntity record) {
        boolean flag = true;
        System.out.println(record.getId());
        // 插入到evaluate_record表。
        int tag = evaluateRecordMapper.insertEvaluateRecord(record);
        System.out.println("tag："+tag);
        if (tag < 1) flag = false;
        // 将关联人员插入到evaluate_record_to_employee表中。
        int recordId = evaluateRecordMapper.selectCurrMaxEvaluateRecordKey();
        // 根据regulationDetailId和times找到每部分的扣减比例。
        RegulationTimes regulationTimes = regulationTimesMapper.selectByDetailIdAndTimes(record.getRegulationDetailId(), record.getTimes());
        EvaluateRecordToEmployee toEmployee = new EvaluateRecordToEmployee();
        EmployeeEntity employee = employeeMapper.selectByCard(record.getEmployeeIdCard());
        // 肇事者employee.
        if (regulationTimes.getPersonalProportion() > 0) {
            toEmployee.setEvaluateRecordId(recordId);
            toEmployee.setEmployeeIdCard(record.getEmployeeIdCard());
            toEmployee.setProportionOfPunishment(regulationTimes.getPersonalProportion());
            tag = toEmployeeMapper.insertEvaluateRecordToEmployee(toEmployee);
            if (tag < 1) flag = false;
            System.out.println("肇事者："+toEmployee.getEmployeeIdCard());
        }
        if (employee.getTeamGroup() != null) {
            // 与肇事者同部门同班组
            if (regulationTimes.getTeamGroupProportion() > 0) {
                List<EmployeeEntity> related = employeeService.selectEmployeesByTeamGroup(employee.getTeamGroup().getId()+"", employee.getDepartment().getDepartmentId());
                if (related.size() > 0) {
                    for (EmployeeEntity rel:related) {
                        TeamGroup teamGroup = employeeService.selectById(employee.getTeamGroup().getId());
                        if (!rel.getIdCard().equals(employee.getIdCard()) && (teamGroup.getBranchManagerId() == null || !teamGroup.getBranchManagerId().equals(rel.getIdCard())) && (teamGroup.getMainManagerId() == null || !teamGroup.getMainManagerId().equals(rel.getIdCard())) ) {// 筛选同一个班组
                            // 如果分管或者主管与肇事者在一个班组，则不加。
                            toEmployee.setEvaluateRecordId(recordId);
                            toEmployee.setEmployeeIdCard(rel.getIdCard());
                            toEmployee.setProportionOfPunishment(regulationTimes.getTeamGroupProportion());
                            tag = toEmployeeMapper.insertEvaluateRecordToEmployee(toEmployee);
                            if (tag < 1) flag = false;
                            System.out.println("同部门同班组："+toEmployee.getEmployeeIdCard());
                        }
                    }
                }
            }
            // 与肇事者同部门不同班组。
            if (regulationTimes.getDepartmentProportion() > 0) {
                List<EmployeeEntity> related = employeeService.selectEmployeesByDepartment(employee.getDepartment().getDepartmentId());
                if (related.size() > 0) {
                    for (EmployeeEntity rel:related) {
                        TeamGroup teamGroup = employeeService.selectById(employee.getTeamGroup().getId());
                        if (rel.getTeamGroup()== null || !rel.getTeamGroup().equals(employee.getTeamGroup())) {
                            if((teamGroup.getBranchManagerId() == null || !teamGroup.getBranchManagerId().equals(rel.getIdCard())) && (teamGroup.getMainManagerId() == null || !teamGroup.getMainManagerId().equals(rel.getIdCard()))) {
                                toEmployee.setEvaluateRecordId(recordId);
                                toEmployee.setEmployeeIdCard(rel.getIdCard());
                                toEmployee.setProportionOfPunishment(regulationTimes.getDepartmentProportion());
                                tag = toEmployeeMapper.insertEvaluateRecordToEmployee(toEmployee);
                                if (tag < 1) flag = false;
                                System.out.println("同部门不同班组："+toEmployee.getEmployeeIdCard());
                            }
                        }
                    }
                }
            }
            // 肇事者的分管
            if (regulationTimes.getBranchManagerProportion() > 0) {
                TeamGroup teamGroup = employeeService.selectById(employee.getTeamGroup().getId());
                if (teamGroup.getBranchManagerId() != null) {
                    toEmployee.setEvaluateRecordId(recordId);
                    toEmployee.setEmployeeIdCard(teamGroup.getBranchManagerId());// 得到的是idCard。
                    toEmployee.setProportionOfPunishment(regulationTimes.getBranchManagerProportion());
                    tag = toEmployeeMapper.insertEvaluateRecordToEmployee(toEmployee);
                    if (tag < 1) flag = false;
                    System.out.println("分管："+toEmployee.getEmployeeIdCard());
                }

            }
            // 肇事者的主管
            if (regulationTimes.getMainManagerProportion() > 0) {
                TeamGroup teamGroup = employeeService.selectById(employee.getTeamGroup().getId());
                if (teamGroup.getMainManagerId() != null) {
                    toEmployee.setEvaluateRecordId(recordId);
                    toEmployee.setEmployeeIdCard(teamGroup.getMainManagerId());
                    toEmployee.setProportionOfPunishment(regulationTimes.getMainManagerProportion());
                    tag = toEmployeeMapper.insertEvaluateRecordToEmployee(toEmployee);
                    if (tag < 1) flag = false;
                    System.out.println("主管："+toEmployee.getEmployeeIdCard());
                }

            }
            // 根据employeeIdCard找到关联人员。
            return flag;
        }
        return flag;
    }

    private String getQuarterStart(Date date) {
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(date);
        //get方法：获取给定日历属性的值，如 endCalendar.get(Calendar.MONTH) 获取日历的月份
        //计算季度数：由于月份从0开始，即1月份的Calendar.MONTH值为0,所以计算季度的第一个月份只需 月份 / 3 * 3
        startCalendar.set(Calendar.MONTH, (((int) startCalendar.get(Calendar.MONTH)) / 3) * 3);
        startCalendar.set(Calendar.DAY_OF_MONTH, 1);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(startCalendar.getTime());
    }

    private String getQuarterEnd(Date date) {
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(date);
        //计算季度数：由于月份从0开始，即1月份的Calendar.MONTH值为0,所以计算季度的第三个月份只需 月份 / 3 * 3 + 2
        endCalendar.set(Calendar.MONTH, (((int) endCalendar.get(Calendar.MONTH)) / 3) * 3 + 2);
        endCalendar.set(Calendar.DAY_OF_MONTH, endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(endCalendar.getTime());
    }
}
